package com.youlian.cloud.gateway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.youlian.cloud.gateway.api.request.TokenAuthRequest;
import com.youlian.cloud.gateway.exception.CloudZuulException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * token校验的拦截器
 *
 * @author : liukx
 * @create : 2018/6/22 14:54
 * @email : liukx@elab-plus.com
 */
@Component
public class TokenFilter extends ZuulFilter {
    private Logger logger = LoggerFactory.getLogger(TokenFilter.class);

    private final String tokenName = "token";

    private final String sceneName = "scene";

    private final String userTypeName = "userType";

    private final String userIdName = "userId";

    private final String filterUrl = "/elab-marketing-authentication/customer/addEcrmUser";

    private final String filterUrl2 = "/elab-marketing-authentication/mcrm/customer/updateOrInsertCustomer";

    /**
     * 拦截器的类型
     *
     * @return
     */
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    /**
     * 拦截器的优先级,越小优先级越高
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return 10;
    }

    /**
     * 是否执行该过滤器
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 该拦截器执行的具体逻辑
     *
     * @return
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        ctx.getResponse().setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        HttpServletRequest request = ctx.getRequest();
        String url = request.getRequestURI();

        // 获取请求的参数
        String token = request.getHeader(tokenName);
        String scene = request.getHeader(sceneName);
        String userType = request.getHeader(userTypeName);
        String userId = request.getHeader(userIdName);

        if (StringUtils.isBlank(token)) {
            token = request.getParameter(tokenName);
            scene = request.getParameter(sceneName);
        }
        // 暂时过滤掉的路由
        if ((filterUrl.equals(url) || filterUrl2.equals(url)) && StringUtils.isBlank(token)) {
            logger.info(url + "  请求必须带token  ");
            throw new CloudZuulException(HttpStatus
                    .UNAUTHORIZED.value(), HttpStatus
                    .UNAUTHORIZED.getReasonPhrase());
        }
        // 如果请求中带有token的话进行校验是否正确
        if (StringUtils.isNotBlank(token) || StringUtils.isNotBlank(userType)) {
            logger.info(" zuul 获取到 token : " + token);
            logger.info(" zuul 获取到 scene : " + scene);
            TokenAuthRequest authRequest = new TokenAuthRequest();
            authRequest.setToken(token);
            authRequest.setUserType(userType);
            authRequest.setUserId(userId);
            Enumeration<String> headerNames = request.getHeaderNames();
            Map<String, String> headerMap = getHeaderMap(request, headerNames);
            authRequest.setPropertyMap(headerMap);
            /*ObjectResponseModel<WorkerAuthResponse> responseModel = null;
            String defaultScene = "ChannelProject";
            if (responseModel != null) {
                WorkerAuthResponse single = responseModel.getSingle();
                if (responseModel.getSuccess() && responseModel.getErrorCode() == null) {
                    logger.info(" token 解析成功 ... " + JSON.toJSONString(single));
                    // 添加参数到head中进行返回
                    ctx.addZuulRequestHeader("workerId", getString(single.getId()));
                    if (StringUtils.isNotBlank(single.getName())) {
                        try {
                            ctx.addZuulRequestHeader("workerName", URLEncoder.encode(single.getName(), "UTF-8"));
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                    }
                    ctx.addZuulRequestHeader("workerMobile", single.getMobile());
                    ctx.addZuulRequestHeader("imAdviser", getString(single.getImAdviser()));
                    ctx.addZuulRequestHeader("videoAdviser", getString(single.getVideoAdviser()));
                    ctx.addZuulRequestHeader("agent", getString(single.getAgent()));
                    ctx.addZuulRequestHeader("houseId", getString(single.getHouseId()));
                    ctx.addZuulRequestHeader("channelRatId", getString(single.getChannelRatId()));
                    ctx.addZuulRequestHeader("channelId", getString(single.getChannelId()));
                } else if (responseModel.getErrorCode() != null && responseModel.getErrorCode().equals(HttpStatus
                        .UNAUTHORIZED.value() + "")) {
                    logger.info(" 该用户无效 " + userId + "\t " + userType);
                    throw new CloudZuulException(HttpStatus
                            .UNAUTHORIZED.value(), HttpStatus
                            .UNAUTHORIZED.getReasonPhrase());
                } else {
                    logger.info(" token验证无效 1 ... " + responseModel.toString());
                }
            } else {
                logger.info(" token验证无效 2 ... " + token);
            }*/
        } else {
            logger.info("跳过鉴权检测 ...");
        }
        return null;
    }

    private Map<String, String> getHeaderMap(HttpServletRequest request, Enumeration<String> headerNames) {
        Map<String, String> dataMap = new LinkedHashMap<>();
        while (headerNames.hasMoreElements()) {
            String key = headerNames.nextElement();
            String value = request.getHeader(key);
            dataMap.put(key, value);
        }
        return dataMap;
    }

    /**
     * 将普通类型转化成String
     *
     * @param o
     * @return
     */
    public String getString(Object o) {
        if (o == null) {
            return null;
        }
        return o.toString();
    }

}
